package com.twang.stock.service;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.twang.stock.common.http.HtmlTools;
import com.twang.stock.dto.StockMinutesMessage;
import com.twang.stock.entity.CompanyCodeInfo;
import com.twang.stock.entity.CompanyStockMinutes;
import com.twang.stock.mapper.CompanyCodeInfoMapper;
import com.twang.stock.mapper.CompanyStockMinutesMapper;
import com.twang.stock.redis.RedisUtil;
import com.twang.stock.rocketMq.RocketMQProducer;
import com.twang.stock.threadPool.AsycTaskExecutorConfig;
import com.twang.stock.utils.date.HolidayCopy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * 复盘提醒
 */
@Slf4j
@Service
public class MinutesStockFixService {


    @Resource
    private AsycTaskExecutorConfig asycTaskExecutorConfig;

    @Resource
    private CompanyCodeInfoMapper companyCodeInfoMapper;

    @Resource
    private CompanyStockMinutesMapper companyStockMinutesMapper;

    @Resource
    private RocketMQProducer rocketMQProducer;

    @Autowired
    private RedisUtil redisUtil;

    private static String COMPANY_STOCK_CODE_LIST = "COMPANY_STOCK_CODE_LIST_MQ_";


    public void initMinutesData(StockMinutesMessage stockMinutesMessage) throws InterruptedException {
        String date = stockMinutesMessage.getDate();
        log.info("==========> 分时修复处理 MinutesStockFixService  initMinutesData  start  date:{} ",stockMinutesMessage.getDate());
        try {
            String[] codes=stockMinutesMessage.getCode().split(",");
            /**
             * map迭代
             */
            CountDownLatch countDownLatch=new CountDownLatch(codes.length);
            for (String code : codes) {
                asycTaskExecutorConfig.taskQueueExecutor().execute(() -> {
                    try{
                        CompanyCodeInfo param=new CompanyCodeInfo();
                        param.setCompanyCode(code);
                        CompanyCodeInfo  item= companyCodeInfoMapper.selectOne(param);
                        if(null==item){
                            return;
                        }
                        if (item.getShortName().contains("退") || item.getShortName().contains("B") || item.getShortName().contains("*ST") || item.getShortName().contains("ST") || item.getShortName().contains("*")) {
                            log.info("==========> 分时修复处理 MinutesStockFixService  initMinutesData  非正规票 companyCode={} shortName={}", item.getCompanyCode(),item.getShortName());
                            return;
                        }
                        List<CompanyStockMinutes> insert = Lists.newArrayList();
                        try {
                            getZDT(insert, item.getCompanyCode(), item.getShortName(), date);
                            if (CollectionUtils.isNotEmpty(insert)) {
                               log.info("==========> 分时修复处理 MinutesStockFixService 剩余size={}",insert.size());
                                insertBatch(insert);
                            }
                        } catch (Exception e) {
                            log.error("==========> 分时修复处理 MinutesStockFixService  initMinutesData  error={}", e);
                        }
                    }finally {
                        countDownLatch.countDown();
                        //log.info("==========> 分时修复处理 MinutesStockFixService  initMinutesData success code={} left={}  ", code, countDownLatch.getCount());
                    }
                });
            }
            countDownLatch.await();
            //批量插入
        } catch (Exception e) {
            log.error("e={}",e);
            throw e;
        }
    }

    public   void  insertBatch(List<CompanyStockMinutes> companyStockMinutes) {
        StockMinutesMessage message = new StockMinutesMessage();
        message.setMinutes(HolidayCopy.getHHmmss().substring(8, 12));
        message.setDate(HolidayCopy.getRealToday());
        message.setCode(companyStockMinutes.get(0).getCompanyName());
        message.setType(StockMinutesMessage.TYPE_INSERT_MINUTES_DB);
        message.setData(companyStockMinutes);
        log.info(">>>>>>>>>>>> insertBatch  send mq size={}", companyStockMinutes.size());
        rocketMQProducer.sendOneWay(JSONObject.toJSONString(message));
    }

    /**
     * 入库
     * @param companyStockMinutes
     */
    public void insertMqBatch(List<CompanyStockMinutes> companyStockMinutes) {
         int num = companyStockMinutesMapper.insertBatch(companyStockMinutes);
        log.info(">>>>>>>>>>>> insertBatch num={}", num);
    }

        public List<CompanyCodeInfo> getCompanyCodeInfos(String date) {
        List<CompanyCodeInfo> list;
        Object object = redisUtil.get(COMPANY_STOCK_CODE_LIST + date);
        if (null != object) {
            list = (List<CompanyCodeInfo>) object;
        } else {
            list = companyCodeInfoMapper.selectAll();
            redisUtil.set(COMPANY_STOCK_CODE_LIST +date, list);
        }
        return list;
    }

    public void getZDT(List<CompanyStockMinutes> insert,String code, String name,String dateTemp) {
        log.info(">>>>>>>>> code={}  name={}  start", code, name);
        List<String> dataList = HtmlTools.httpTenXun(code);
        String result = dataList.get(0);
        List<String> strings = JSONObject.parseArray(result, String.class);
        if(strings.size()<200){
            return;
        }
        BigDecimal yesterDayPrice=BigDecimal.ZERO;
        CompanyStockMinutes last =null; //insert.get(insert.size() - 1);
        List<String> dates = companyStockMinutesMapper.queryDates();
        List<CompanyStockMinutes> companyStockMinutesList = null;
        for (int i = 0; i < strings.size(); i++) {
            try {
                String[] data = strings.get(i).split(" ");
                //
                CompanyStockMinutes temp = new CompanyStockMinutes();
                if (StringUtils.isNotEmpty(dateTemp)) {
                    temp.setDate(dateTemp);
                } else {
                    temp.setDate(HolidayCopy.getRealToday());
                }
                //temp.setDate("20230614");
                temp.setCompanyCode(code);
                if ((data[0].startsWith("15")) && !"1500".equals(data[0])) {
                    continue;
                } else {
                    temp.setMinutes(data[0]);
                }
                //companyStockMinutesMapper.delete(temp);
                CompanyStockMinutes companyStockMinutes = new CompanyStockMinutes();
                companyStockMinutes.setCompanyCode(code);
                companyStockMinutes.setCompanyName(name);
                companyStockMinutes.setMinutes(temp.getMinutes());
                companyStockMinutes.setDate(temp.getDate());
                companyStockMinutes.setPrice(new BigDecimal(data[1]));
                companyStockMinutes.setTradeVol(new BigDecimal(data[2]));
                companyStockMinutes.setTradeSum(new BigDecimal(data[3]));
                companyStockMinutes.setCreateTime(new Date());
                if (i == 0) {
                    companyStockMinutes.setVol(new BigDecimal(data[2]));
                    companyStockMinutes.setAmount(new BigDecimal(data[3]));
                    //List<String> dates = companyStockMinutesMapper.queryDates();
                    /** 昨天 */
                    if (CollectionUtils.isEmpty(companyStockMinutesList)) {
                        String date = dates.get(dates.size() - 2);
                        companyStockMinutesList = companyStockMinutesMapper.queryYesterDayInfo(companyStockMinutes.getCompanyCode(), date);

                    }
                    if (CollectionUtils.isNotEmpty(companyStockMinutesList)) {
                        yesterDayPrice = companyStockMinutesList.get(0).getPrice();
                    }
                    try{
                        companyStockMinutes.setZhangDie((companyStockMinutes.getPrice().subtract(yesterDayPrice).divide(yesterDayPrice, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))));
                    }catch (Exception e){
                        log.info(">>>>>>>> 计算涨跌异常：{}",companyStockMinutes.getCompanyCode());
                    }
                } else {
                    if (null != last) {
                        try{
                            companyStockMinutes.setZhangDie((companyStockMinutes.getPrice().subtract(yesterDayPrice).divide(yesterDayPrice, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))));
                        }catch (Exception e){
                            log.info(">>>>>>>> 计算涨跌异常：{}",companyStockMinutes.getCompanyCode());
                        }
                        companyStockMinutes.setVol(companyStockMinutes.getTradeVol().subtract(last.getTradeVol()));
                        companyStockMinutes.setAmount(companyStockMinutes.getTradeSum().subtract(last.getTradeSum()));
                    }
                }
                //
                if ("1500".equals(companyStockMinutes.getMinutes())) {
                    try{
                        companyStockMinutes.setZhangDie(HtmlTools.httpGet( code).get(0).getPriceChangePercentage());
                    }catch (Exception e){
                        log.info(">>>>>>>> 计算涨跌异常：{}",companyStockMinutes.getCompanyCode());
                    }
                }
                if (insert.size() == 242) {
                    //批量插入
                    insertBatch(insert);
                    insert.clear();
                }
                //companyStockMinutesMapper.insert(companyStockMinutes);
                insert.add(companyStockMinutes);
                last=companyStockMinutes;
            } catch (Exception e) {
                log.error(">>>>>> str={} error={}", strings.get(i), e);
                throw e;
            }
        }
        log.info(">>>>>>>>> code={}  name={}  end size={}", code, name, strings.size());
    }

    public static String calculatePreviousMinute(String currentTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HHmm");
        LocalTime time = LocalTime.parse(currentTime, formatter);
        LocalTime previousMinute = time.minusMinutes(1);
        return previousMinute.format(formatter);
    }

}
